<?php

declare(strict_types=1);

namespace ImiApp\ApiServer\Common;

use Imi\Bean\Annotation\Bean;

// use \Imi\Redis\Redis;
use Redis;

/**
 * @Bean("RedisGeo")
 */
class RedisGeo extends Bean
{

    public function __construct()
    {
        var_dump('RedisGeo __construct');
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('8622efe3bada2cc2');
        $this->redis = $redis;
    }

    /**
     * {@inheritDoc}
     */
    public function geoadd(?float $lng, ?float $lat, ?string $id, $name = 'geo:store')
    {
        $result = $this->redis->geoadd($name,  $lng, $lat, $id);
        if (!$result) {
            var_dump(__METHOD__ . 'getLastError', $this->redis->getLastError());
        }
        return $result;
    }

    /**
     * 获取附近的列表
     *
     * @param float $lng 经度
     * @param float $lat 纬度
     * @param int $m 距离多远
     * @param string $unit 单位:m米,km千米,mi英里,ft英尺
     * @param int $limit 需要的数量
     * @param string $sort 排序ASC,DESC
     * @param string $name 用于分类名
     * @return void
     */
    public function get_nearby_list($lng,  $lat, $m = 1000, $unit = 'm', $limit = 5, $sort = 'ASC', $name = 'geo:store')
    {
        if ($limit < 1) {
            $limit = 10;
        } else {
            $limit = intval($limit);
        }
        $list = $this->redis->georadius($name, floatval($lng), floatval($lat), floatval($m), $unit, ['WITHDIST', 'COUNT' => $limit, $sort]);
        if ($list === false) {
            var_dump(__METHOD__ . 'getLastError', $this->redis->getLastError());
        }
        return $list;
    }



    /**
     * 获取信息
     *
     * @param string $id 添加时候的信息
     * @return void
     */
    public function get_data($id, $name = 'geo:store')
    {
        $data = $this->redis->geopos($name, $id);
        return $data;
    }

    /**
     * 删除某个坐标
     *
     * @param int $id 数据id
     * @param string $name 用于分类名
     * @return void
     */
    public function del_geo($id, $name = 'geo:store')
    {
        $this->redis->zrem($name, $id);
    }

    /**
     * 删除全部地理坐标
     * 
     * @param string $name 用于分类名
     * @return void
     */
    public function del_geo_all($name = 'geo:store')
    {

        $nums = $this->redis->zcard($name);
        $list = $this->redis->zrange($name, 0, $nums);
        if (\Imi\App::isDebug()) {//开发模式才可删除
            foreach ($list as $key => $value) {
                $this->del_geo($value, $name);
            }
        }
        return $nums;
    }


    /**
     * 获取2个坐标距离(km)
     * @param $lng1 经度1
     * @param $lat1 纬度1
     * @param $lng2 经度2
     * @param $lat2 纬度2
     * @return float
     */
    public function get_coordinate_distance($lng1 = 120.459799, $lat1 = 31.802264, $lng2 = 120.326568, $lat2 = 31.686598)
    {
        $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度
        $radLat2 = deg2rad($lat2);
        $radLng1 = deg2rad($lng1);
        $radLng2 = deg2rad($lng2);
        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;
        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137;
        return $s;
    }
}
